<template>
  <span :class="['input-number', $slots.append ? 'append' : '']">
    <el-input-number 
      v-model="numberValue"
      :controls="showControls"
      controls-position="right"
      :step="precision === 1 ? 0.1 : precision === 2 ? 0.01 : 1"
      :precision="precision"
      :min="min"
      :max="max"
      :disabled="disabled"
      :readonly="readonly"
      :size="size"
      @change="handleChange"
      @blur="handleBlur"
    />
    <span class="append-box" v-if="$slots.append">
      <slot name="append" />
    </span>
  </span>
</template>

<script setup>
import { onBeforeMount, ref, watch, nextTick } from 'vue';
import { useDisabled } from 'element-plus';

const emit = defineEmits(['update:modelValue', 'change', 'blur']);
const props = defineProps({
  modelValue: {
    type: [String, Number],
    default: ''
  },
  point: {
    type: [String, Number],
    default: 0
  },
  min: {
    type: Number,
    default: -Infinity
  },
  max: {
    type: Number,
    default: Infinity
  },
  size: String,
  placeholder: String,
  disabled: Boolean,
  readonly: Boolean,
  showControls: {
    type: Boolean,
    default: true
  }
});

const min = ref(0);
const max = ref(2147483647);
const numberValue = ref(undefined);
const precision = ref(parseInt((props.point || '0')));
const disabled = ref(false);
const readonly = ref(false);
const inputDisabled = useDisabled();

const init = (data) => {
  min.value = data.min || min.value;
  max.value = data.max || max.value;
  precision.value = parseInt((data.point || '0'));
  disabled.value = inputDisabled.value || data.disabled || false;
  readonly.value = data.readonly || false;

  if (typeof data.modelValue === "undefined" || data.modelValue == null || data.modelValue === '') {
    numberValue.value = undefined;
  } else {
    numberValue.value = parseFloat(data.modelValue + '');
  }
  emit('update:modelValue', numberValue.value);
};

const handleChange = () => {
  emit('update:modelValue', numberValue.value);
  nextTick(() => {
    emit('change', numberValue.value);
  });
};

const handleBlur = () => {
  emit('update:modelValue', numberValue.value);
  nextTick(() => {
    emit('blur', numberValue.value);
  });
};

watch(() => props, (newVal) => {
  init(newVal);
}, {deep: 1});

onBeforeMount(() => {
  init(props);
});
</script>

<style scoped>
.input-number {
  display: flex;
  flex-direction: row;
  width: 100%;
}
.input-number :deep(.el-input-number) {
  width: 100%;
}
.input-number :deep(.el-input-number--small) {
  padding: 0;
  text-align: left;
  width: 100%;
}
.input-number :deep(.el-input-number .el-input__inner) {
  text-align: left;
}
.input-number.append :deep(.el-input__wrapper) {
  border-top-right-radius: 0!important;
  border-bottom-right-radius: 0!important;
}
.input-number :deep(.append-box) {
  background-color: #f5f7fa;
  color: #909399;
  border: 1px solid #dcdfe6;
  border-left: none;
  border-top-right-radius: 4px;
  border-bottom-right-radius: 4px;
  padding: 0 10px;
  white-space: nowrap;
  height: 30px;
  line-height: 30px;
}
</style>